package com.zhouxiaoxuan13.consumer.controller;

import brave.Span;
import brave.Tracer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.TimeUnit;

/**
 * 链路跟踪测试控制器（消费者服务）
 * 用于演示跨服务的分布式链路跟踪功能
 */
@Slf4j
@RestController
@RequestMapping("/api/tracing-test")
@CrossOrigin(origins = "*")
public class TracingTestController {

    @Autowired
    private Tracer tracer;

    // 移除ObservationRegistry，使用Brave API

    // 注释掉Feign客户端，简化测试
    // @Autowired
    // private PromotionServiceClient promotionServiceClient;

    // @Autowired
    // private FreshProductServiceClient freshProductServiceClient;

    @Autowired
    private RestTemplate restTemplate;

    @Value("${server.port}")
    private String serverPort;

    @Value("${spring.application.name}")
    private String applicationName;

    private final Random random = new Random();

    /**
     * 跨服务链路跟踪测试 - 使用RestTemplate
     */
    @GetMapping("/cross-service-feign")
    public ResponseEntity<Map<String, Object>> crossServiceTracingWithFeign() {
        log.info("=== 跨服务链路跟踪测试开始（RestTemplate） ===");

        Span mainSpan = tracer.nextSpan()
                .name("cross-service-rest-operation")
                .tag("service.name", applicationName)
                .tag("service.port", serverPort)
                .tag("operation.type", "cross-service-rest")
                .start();

        try (Tracer.SpanInScope ws = tracer.withSpanInScope(mainSpan)) {
            Map<String, Object> response = createResponse("跨服务链路跟踪测试（RestTemplate）");

            try {
                // 第一步：调用促销服务8001
                log.info("步骤1: 调用促销服务8001");
                String url1 = "http://localhost:8001/api/tracing/basic";
                @SuppressWarnings("rawtypes")
                ResponseEntity result1 = restTemplate.getForEntity(url1, Map.class);
                response.put("step1_service8001", result1.getBody());

                // 模拟处理时间
                simulateBusinessLogic("处理服务8001响应", 50, 100);

                // 第二步：调用促销服务8002
                log.info("步骤2: 调用促销服务8002");
                String url2 = "http://localhost:8002/api/tracing/basic";
                @SuppressWarnings("rawtypes")
                ResponseEntity result2 = restTemplate.getForEntity(url2, Map.class);
                response.put("step2_service8002", result2.getBody());

                // 模拟处理时间
                simulateBusinessLogic("处理服务8002响应", 30, 80);

                // 获取当前Span信息
                Span currentSpan = tracer.currentSpan();
                if (currentSpan != null) {
                    response.put("traceId", currentSpan.context().traceId());
                    response.put("spanId", currentSpan.context().spanId());
                }

                response.put("totalSteps", 2);
                response.put("allStepsCompleted", true);

                log.info("=== 跨服务链路跟踪测试完成（RestTemplate） ===");
                return ResponseEntity.ok(response);

            } catch (Exception e) {
                log.error("跨服务调用失败", e);
                response.put("error", true);
                response.put("errorMessage", e.getMessage());
                response.put("errorType", e.getClass().getSimpleName());

                // 在Span中记录错误
                mainSpan.tag("error", "true")
                       .tag("error.message", e.getMessage())
                       .tag("error.type", e.getClass().getSimpleName());
                response.put("traceId", mainSpan.context().traceId());
                response.put("spanId", mainSpan.context().spanId());

                return ResponseEntity.status(500).body(response);
            }
        } finally {
            mainSpan.finish();
        }
    }

    /**
     * 跨服务链路跟踪测试 - 使用RestTemplate
     */
    @GetMapping("/cross-service-rest")
    public ResponseEntity<Map<String, Object>> crossServiceTracingWithRest() {
        log.info("=== 跨服务链路跟踪测试开始（RestTemplate） ===");
        
        Span mainSpan = tracer.nextSpan()
                .name("cross-service-rest-operation")
                .tag("service.name", applicationName)
                .tag("service.port", serverPort)
                .tag("operation.type", "cross-service-rest")
                .start();

        try (Tracer.SpanInScope ws = tracer.withSpanInScope(mainSpan)) {
            Map<String, Object> response = createResponse("跨服务链路跟踪测试（RestTemplate）");
            
            // 第一步：调用促销服务8001
            performRestCall("promotion-service-8001", "http://localhost:8001/api/tracing/basic", response, "step1");
            
            // 第二步：调用促销服务8002
            performRestCall("promotion-service-8002", "http://localhost:8002/api/tracing/complex", response, "step2");
            
            // 第三步：调用网关
            performRestCall("gateway-service", "http://localhost:9527/actuator/health", response, "step3");
            
            response.put("traceId", mainSpan.context().traceId());
            response.put("spanId", mainSpan.context().spanId());
            response.put("totalSteps", 3);
            response.put("allStepsCompleted", true);
            
            log.info("=== 跨服务链路跟踪测试完成（RestTemplate） ===");
            return ResponseEntity.ok(response);
            
        } catch (Exception e) {
            log.error("跨服务调用失败", e);
            Map<String, Object> errorResponse = createResponse("跨服务链路跟踪测试（RestTemplate）- 错误");
            errorResponse.put("error", true);
            errorResponse.put("errorMessage", e.getMessage());
            errorResponse.put("traceId", mainSpan.context().traceId());
            errorResponse.put("spanId", mainSpan.context().spanId());
            
            mainSpan.tag("error", "true")
                   .tag("error.message", e.getMessage());
            
            return ResponseEntity.status(500).body(errorResponse);
        } finally {
            mainSpan.finish();
        }
    }

    /**
     * 链路跟踪信息查询
     */
    @GetMapping("/info")
    public ResponseEntity<Map<String, Object>> getTracingInfo() {
        Map<String, Object> response = createResponse("链路跟踪信息查询");
        
        Span currentSpan = tracer.currentSpan();
        if (currentSpan != null) {
            response.put("hasActiveTrace", true);
            response.put("traceId", currentSpan.context().traceId());
            response.put("spanId", currentSpan.context().spanId());
        } else {
            response.put("hasActiveTrace", false);
            response.put("message", "当前没有活跃的链路跟踪");
        }
        
        response.put("zipkinEndpoint", "http://localhost:9411");
        response.put("tracingEnabled", true);
        
        return ResponseEntity.ok(response);
    }

    /**
     * 执行REST调用
     */
    private void performRestCall(String serviceName, String url, Map<String, Object> response, String stepKey) {
        Span restSpan = tracer.nextSpan()
                .name("rest-call-" + serviceName)
                .tag("service.target", serviceName)
                .tag("http.url", url)
                .start();

        try (Tracer.SpanInScope ws = tracer.withSpanInScope(restSpan)) {
            log.info("调用服务: {} - {}", serviceName, url);
            
            @SuppressWarnings("rawtypes")
            ResponseEntity result = restTemplate.getForEntity(url, Map.class);
            response.put(stepKey + "_" + serviceName, result.getBody());
            response.put(stepKey + "_status", result.getStatusCodeValue());
            
            restSpan.tag("http.status_code", String.valueOf(result.getStatusCodeValue()))
                   .tag("operation.status", "success");
            
            // 模拟处理时间
            simulateBusinessLogic("处理" + serviceName + "响应", 20, 50);
            
        } catch (Exception e) {
            log.error("调用服务失败: {} - {}", serviceName, url, e);
            response.put(stepKey + "_error", e.getMessage());
            
            restSpan.tag("error", "true")
                   .tag("error.message", e.getMessage())
                   .tag("operation.status", "failed");
            throw e;
        } finally {
            restSpan.finish();
        }
    }

    /**
     * 模拟业务逻辑处理
     */
    private void simulateBusinessLogic(String operation, int minDelay, int maxDelay) {
        try {
            int delay = random.nextInt(maxDelay - minDelay + 1) + minDelay;
            log.info("模拟 {} 处理，耗时: {}ms", operation, delay);
            TimeUnit.MILLISECONDS.sleep(delay);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new RuntimeException("操作被中断", e);
        }
    }

    /**
     * 创建响应对象
     */
    private Map<String, Object> createResponse(String operation) {
        Map<String, Object> response = new HashMap<>();
        response.put("operation", operation);
        response.put("serviceName", applicationName);
        response.put("servicePort", serverPort);
        response.put("timestamp", LocalDateTime.now());
        response.put("success", true);
        return response;
    }
}
